home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xsw
/
libkmem.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-09
|
8KB
|
285 lines
/*
* @(#) libkmem.c 12.1 95/05/09 SCOINC
*/
/***************************************************************************
*
* Copyright (c) 1990-1993 The Santa Cruz Operation, Inc.
*
* All rights reserved. No part of this program or publication may be
* reproduced, transmitted, transcribed, stored in a retrieval system,
* or translated into any language or computer language, in any form or
* by any means, electronic, mechanical, magnetic, optical, chemical,
* biological, or otherwise, without the prior written permission of:
*
* The Santa Cruz Operation , Inc. (408) 425-7222
* 400 Encinal St., Santa Cruz, California 95060 USA
*
**************************************************************************/
/*
* Modification History
*
* S003, 24-Oct-93, rickra
* Removed the include of xswnlist.h
*
* S002, 27-May-93, rickra
* Woops, had a bad end of comment in Modification History.
*
* S001, 27-May-93, rickra
* Added some code to do virtual to pysical address translations. The
* idea being xsw could possibly be used on a system dump...... Much
* like "crash"...... Just an idea.....
*
* S000, 30-Sep-92, rickra
* Added copyright and modification history
*/
/*LINTLIBRARY*/
/*+-------------------------------------------------------------------------
libkmem.c -- /dev/kmem routines for SCO UNIX/386 (maybe other *NIX)
...!{gatech,emory}!n4hgf!wht
Defined functions:
kinit(write_needed)
kread(caddr,kaddr,len)
kwrite(kaddr,caddr,len)
routines were originally written by Mike "Ford" Ditto: kudos!!!
--------------------------------------------------------------------------*/
/*+:EDITS:*/
/*:09-25-1990-05:11-wht@n4hgf-release heh-heh x0.22 preliminary */
/*:09-20-1990-00:09-wht@n4hgf-scales, sysinfo/minfo, bootinfo working */
/*:09-15-1990-06:32-wht@n4hgf-adopt u386mon libraries */
/*:08-10-1990-14:12-jmd@p1so/wht@n4hgf-2.20-add Tandem Integrity S2 */
/*:08-07-1990-14:24-wht@n4hgf-nba@sysware.sysware.dk S5R31 updates */
/*:08-02-1990-15:36-wht@n4hgf-2.12-old curses hacks+minor 3.2 formalizations */
/*:08-01-1990-19:33-jdc@dell.com-add more error text */
/*:07-28-1990-18:06-wht@n4hgf-2.10 release */
/*:06-27-1990-01:57-wht@n4hgf-1.10-incorporate suggestions from alpha testers */
/*:06-25-1990-04:14-wht@n4hgf-1.02-better error handling */
/*:06-24-1990-20:53-wht@n4hgf-v1.01-add ISC support thanks to peter@radig.de */
/*:06-21-1990-14:26-r@n4hgf-version x0.12 seems bug free */
/*:12-07-1988-22:06-wht-put in test for initialized fdkmem */
/*:10-27-1988-22:44-wht-creation of file */
#include <sys/types.h>
#include <sys/errno.h>
#include <fcntl.h>
#include "include/unixincs.h"
#include "include/libkmem.h"
#include <syms.h>
void leave_text ();
extern int errno;
static int fdkmem = -2;
daddr_t lseek ();
/*+-------------------------------------------------------------------------
kinit(write_needed)
--------------------------------------------------------------------------*/
void
kinit (write_needed)
int write_needed;
{
if (fdkmem >= 0)
return;
if ((fdkmem = open ("/dev/kmem", (write_needed) ? O_RDWR : O_RDONLY, 0)) < 0)
{
if (write_needed)
{
leave_text ("can't open /dev/kmem for read/write access", 255);
}
else
{
leave_text ("can't open /dev/kmem for read access", 255);
}
}
} /* end of kinit */
/*+-------------------------------------------------------------------------
kread(caddr,kaddr,len)
--------------------------------------------------------------------------*/
void
kread (caddr, kaddr, len)
caddr_t caddr;
daddr_t kaddr;
int len;
{
char s80[80];
#if defined(M_I286)
kaddr &= 0xFFFFL;
#endif
#if defined(mips)
kaddr &= 0x7FFFFFFFL;
#endif
if (fdkmem == -2)
leave_text ("kinit() not called", 1);
if (lseek (fdkmem, kaddr, 0) == -1L)
{
(void) sprintf (s80, "kmem read seek error addr %08lx", kaddr);
leave_text (s80, 255);
}
if (read (fdkmem, caddr, len) != len)
{
(void) sprintf (s80, "kmem read error len %d addr %08lx", len, kaddr);
leave_text (s80, 255);
}
} /* end of kread */
/*+-------------------------------------------------------------------------
kwrite(kaddr,caddr,len)
--------------------------------------------------------------------------*/
#ifdef KWRITE_NEEDED
void
kwrite (kaddr, caddr, len)
daddr_t kaddr;
caddr_t caddr;
int len;
{
char s80[80];
#if defined(M_I286)
kaddr &= 0xFFFFL;
#endif
if (fdkmem == -2)
leave_text ("kinit() not called", 1);
if (lseek (fdkmem, kaddr, 0) == -1L)
{
(void) sprintf (s80,
"/dev/kmem write seek error addr %08lx", kaddr);
leave_text (s80, 255);
}
if (write (fdkmem, caddr, len) != len)
{
(void) sprintf (s80,
"/dev/kmem write error addr %08lx len %08lx", kaddr, len);
leave_text (s80, 255);
}
} /* end of kwrite */
#endif
#ifdef DO_WE_NEED_THIS
/*
* The following code was take from "crash". Minor modifications where done
* to incorporate it into xsw. Why re-write code!!
*/
/* determine valid process table entry */
int
procntry (slot, prbuf)
int slot;
struct proc *prbuf;
{
if (slot == -1)
slot = getcurproc ();
if ((slot > vbuf.v_proc) || (slot < 0))
error ("%d out of range\n", slot);
readmem ((long) (Proc -> n_value + slot * sizeof (struct proc)), 1, -1,
(char *) prbuf, sizeof (struct proc), "process table");
if (!prbuf -> p_stat)
error (" %d is not a valid process\n", slot);
}
int abortflag = 0;
struct proc prbuf;
paddr_t
vtop (vaddr, slot)
unsigned long vaddr;
int slot;
{
#define errtx(tx) {if(!abortflag)return(-1);abortflag=0;printf(tx);}
static pde_t *KPD;
pde_t pde, *pd;
preg_t preg, *ppreg;
reg_t reg;
caddr_t hi, lo;
int debugmode = 0;
/* Get kernel page directory */
if (!KPD)
{
KPD = (pde_t *) (x[BX_KPD0].n_value - KVSBASE);
}
pd = KPD + ptnum (vaddr);
if (debugmode > 1)
fprintf (stderr, "vtop(%x,%d): ", vaddr, slot);
if KADDR
(vaddr)
{
if (debugmode > 1)
fprintf (stderr, "kvirt ");
}
else
{
if (debugmode > 1)
fprintf (stderr, "must be transformed.\n");
/*
* To Need to find this procedure!!!!
*/
procntry (slot, &prbuf);
if (!(prbuf.p_flag & SLOAD))
fprintf (stdout, "proc is swapped out\n");
if (vaddr >= UVUBLK && pfnum (vaddr - UVUBLK) < MAXUSIZE)
{
pde = prbuf.p_ubptbl[pfnum (vaddr - UVUBLK)];
goto got_pte;
}
else if (vaddr < MAXUVADR)
{
for (ppreg = prbuf.p_region;; ppreg++)
{
readmem (ppreg, 1, slot, &preg, sizeof (preg), "pregion");
if (preg.p_reg == NULL)
break;
readmem (preg.p_reg, 1, slot, ®, sizeof (reg),
"region table entry");
if (preg.p_type == PT_STACK)
{
lo = preg.p_regva - ctob (reg.r_pgsz) + 1;
hi = preg.p_regva + 1;
}
else
{
lo = preg.p_regva;
hi = preg.p_regva + ctob (reg.r_pgsz);
}
if (vaddr < (ulong) lo || vaddr >= (ulong) hi)
continue;
readmem (reg.r_list + ctost (btoct (vaddr - (ulong) preg.p_regva)),
1, slot, &pd, sizeof (pd),
"page table pointer");
readmem (pd + pnum (vaddr), 1, slot, &pde, sizeof (pde),
"page table entry");
goto got_pte;
}
}
}
readmem (pd, 0, slot, &pde, sizeof (pde), "page directory entry");
if (!(pde.pgm.pg_pres))
errtx ("Page Table not in core\n");
readmem ((pde_t *) ctob (pde.pgm.pg_pfn) + pnum (vaddr),
0, slot, &pde, sizeof (pde), "page table entry");
got_pte:
if (!(pde.pgm.pg_pres))
errtx ("Page not in core\n");
return (ctob (pde.pgm.pg_pfn) + poff (vaddr));
}
#endif
/* vi: set tabstop=4 shiftwidth=4: */